<html>
<head><meta charset="utf-8"><title>does Repr(C) on a single field struct hurts optimizations? · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html">does Repr(C) on a single field struct hurts optimizations?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="245053355"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245053355" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245053355">(Jul 06 2021 at 15:16)</a>:</h4>
<p>It seems like adding <code>#[repr(C)]</code> can make huge impact on codegen in places that seem like the result should be the same?<br>
The code:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="c1">//#[repr(C)]</span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">Wrapper</span><span class="p">(</span><span class="kt">usize</span><span class="p">);</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">conv</span><span class="p">(</span><span class="n">msgs</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="kt">usize</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Wrapper</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">msgs</span><span class="p">.</span><span class="n">into_iter</span><span class="p">().</span><span class="n">map</span><span class="p">(</span><span class="n">Wrapper</span><span class="p">).</span><span class="n">collect</span><span class="p">()</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Godbolt: <a href="https://godbolt.org/z/d69aaK3b9">https://godbolt.org/z/d69aaK3b9</a><br>
if you uncomment the repr(c) you'll see the assembly gets much bigger.</p>



<a name="245053777"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245053777" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> marmeladema <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245053777">(Jul 06 2021 at 15:18)</a>:</h4>
<p>If you use <code>#[repr(transparent)]</code> you get the same assembly as without the repr attribute</p>



<a name="245053856"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245053856" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245053856">(Jul 06 2021 at 15:18)</a>:</h4>
<p>Another related find is the codegen of this compared to the one above:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">Wrapper</span><span class="p">(</span><span class="kt">usize</span><span class="p">);</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">conv</span><span class="p">(</span><span class="n">msgs</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="kt">usize</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Wrapper</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">msgs</span><span class="p">.</span><span class="n">into_iter</span><span class="p">().</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">m</span><span class="o">|</span><span class="w"> </span><span class="n">m</span><span class="p">).</span><span class="n">collect</span><span class="p">()</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p><a href="https://godbolt.org/z/Ts9qq88z4">https://godbolt.org/z/Ts9qq88z4</a></p>
<p>Credit: <span class="user-mention" data-user-id="219793">@joey</span>  in IRC</p>



<a name="245054066"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245054066" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> joey <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245054066">(Jul 06 2021 at 15:20)</a>:</h4>
<p>This is the more interesting one ^</p>



<a name="245054190"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245054190" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> joey <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245054190">(Jul 06 2021 at 15:21)</a>:</h4>
<p><a href="https://godbolt.org/z/jMe7vxcnn">https://godbolt.org/z/jMe7vxcnn</a> comparing one that gets optimised, and another that doesnt</p>



<a name="245054416"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245054416" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245054416">(Jul 06 2021 at 15:22)</a>:</h4>
<p>It seems lik also the LLVM IR is very different (both with a closure and with <code>core::convert::identity</code>)</p>



<a name="245055173"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245055173" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245055173">(Jul 06 2021 at 15:27)</a>:</h4>
<p>C ABI often treats "struct with single int field" differently from "single int"</p>



<a name="245055377"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245055377" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> joey <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245055377">(Jul 06 2021 at 15:29)</a>:</h4>
<p>(I think the topic was a bit of a misdirection, the real issue seems to be the jME7.. link I pasted)</p>



<a name="245055385"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245055385" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245055385">(Jul 06 2021 at 15:29)</a>:</h4>
<p>as soon as the layout of <code>usize</code> and <code>Wrapper</code> differs, the in-place collect optimization will be impossible</p>



<a name="245055497"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245055497" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245055497">(Jul 06 2021 at 15:29)</a>:</h4>
<p>hmm, though I wouldn't expect this to happen for x86_64</p>



<a name="245055707"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245055707" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> joey <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245055707">(Jul 06 2021 at 15:31)</a>:</h4>
<p>look at <a href="https://godbolt.org/z/jMe7vxcnn">https://godbolt.org/z/jMe7vxcnn</a> theyre the same type and it defeats the in-place opt!</p>



<a name="245057197"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245057197" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Giacomo Stevanato <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245057197">(Jul 06 2021 at 15:41)</a>:</h4>
<p>Technically the inplace optimization is still there in all these examples, what's going wrong is the elision of loops with empty bodies. Look for example at .LBB0_7 in the last example you linked</p>



<a name="245060306"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245060306" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245060306">(Jul 06 2021 at 16:00)</a>:</h4>
<p>That's <a href="https://github.com/rust-lang/rust/issues/79308">#79308</a></p>



<a name="245060547"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245060547" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> joey <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245060547">(Jul 06 2021 at 16:01)</a>:</h4>
<p><span class="user-mention" data-user-id="330154">@The 8472</span> heh cool, nearly exact the same test case</p>



<a name="245060991"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245060991" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245060991">(Jul 06 2021 at 16:04)</a>:</h4>
<p>I tried adding an additional optimization to eliminate that loop based on <code>TrustedLen</code> (an existing optimization requires <code>TrustedRandomAccess</code> which needs <code>T: Copy</code>) but it hasn't been reliable. When I do microbenchmarks it optimizes away, when I write a codegen tests the loop is suddenly back. :(<br>
So, if you derive Copy for your <code>Wrapper</code> it might work for now.</p>



<a name="245061292"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245061292" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245061292">(Jul 06 2021 at 16:06)</a>:</h4>
<p>Hrm, no, doesn't look like it, interesting.</p>



<a name="245063147"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245063147" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245063147">(Jul 06 2021 at 16:20)</a>:</h4>
<p>Adding <code>Copy</code> works for the plain wrapper, but it doesn't for the <code>repr(C)</code> one.</p>



<a name="245547179"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245547179" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245547179">(Jul 10 2021 at 12:20)</a>:</h4>
<p><span class="user-mention" data-user-id="249222">@Elichai Turkel</span> indeed this is why the C++ people are regretting their choices around <code>unique_ptr</code>... it's a single-field "repr(C)" struct and as such has a lot of overhead compared to just passing a pointer. and they can't change it as that would be ABI-breaking...</p>



<a name="245566260"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245566260" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alexander Huszagh (He/Him) <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245566260">(Jul 10 2021 at 19:09)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/122651-general/topic/does.20Repr.28C.29.20on.20a.20single.20field.20struct.20hurts.20optimizations.3F/near/245547179">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="249222">Elichai Turkel</span> indeed this is why the C++ people are regretting their choices around <code>unique_ptr</code>... it's a single-field "repr(C)" struct and as such has a lot of overhead compared to just passing a pointer. and they can't change it as that would be ABI-breaking...</p>
</blockquote>
<p>For <code>unique_ptr</code>, isn't that only with a stateful allocator (well, deleter), since tuples/compressed pairs use empty-base optimization? Which, I'm not really sure there is an alternative.</p>



<a name="245566537"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245566537" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245566537">(Jul 10 2021 at 19:16)</a>:</h4>
<p>It can't be passed in a register is the issue, since it's non-trivial for the purposes of calls.</p>



<a name="245575446"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245575446" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245575446">(Jul 10 2021 at 22:39)</a>:</h4>
<p><code>unique_ptr</code> <em>should</em> be like <code>Box</code> -- but it isnt: in Rust terms, <code>Box</code> is <code>repr(transparent)</code>; <code>unique_ptr</code> is <code>repr(C)</code>.<br>
the difference (as was said above) is whether the pointer is passed via register or via stack.</p>



<a name="245575896"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245575896" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245575896">(Jul 10 2021 at 22:51)</a>:</h4>
<p>The deleter makes that fun: Not only does <code>unique_ptr</code> allow choosing a deleter, you could also customize the behaviour of <code>std::default_delete</code>, where passing in a register would be invalid. Of course, that could be done by special-casing, but it would be a lot narrower of a special case than <code>Box&lt;T,Global&gt;</code>, so one could argue whether that special case is worth it.</p>



<a name="245587384"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/does%20Repr%28C%29%20on%20a%20single%20field%20struct%20hurts%20optimizations%3F/near/245587384" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alexander Huszagh (He/Him) <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/does.20Repr(C).20on.20a.20single.20field.20struct.20hurts.20optimizations.3F.html#245587384">(Jul 11 2021 at 04:28)</a>:</h4>
<p>Ah.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>